package uk.co.hs.domain.web;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.ForeignKey;
import org.hibernate.annotations.Index;
import org.hibernate.annotations.Type;
import org.joda.time.DateTime;

import uk.co.hs.domain.generic.UtilisoftGenericDomain;

@Entity
@org.hibernate.annotations.Table(appliesTo=WebUser.TABLE_NAME,
                                 indexes={@Index(name=WebUser.TABLE_NAME + "_IDX_1", columnNames={UtilisoftGenericDomain.PK, UtilisoftGenericDomain.VERSION}),
                                          @Index(name=WebUser.TABLE_NAME + "_IDX_2", columnNames=WebUser.ROLE_FK)})
@Table(name=WebUser.TABLE_NAME)
public class WebUser extends UtilisoftGenericDomain<Long>
{
  private static final long serialVersionUID = 1L;

  protected static final String TABLE_NAME = "WEB_USER";
  protected static final String ROLE_FK = "ROLE_FK";

  public static final String UTILISOFT_USER = "utilisoft";

  private String mUsername;
  private String mPassword;
  private Boolean mActive;
  private Boolean mLocked;
  private Boolean mNewPasswordRequired;
  private int mConsecutiveFailedLogins;
  private DateTime mEndDate;
  private DateTime mLastPasswordChanged;
  private WebRole mRole;
  private List<WebPasswordHistory> mPasswordHistory;
  private String mPreferences;

  /**
   * Default Constructor.
   */
  public WebUser()
  {
    super();
  }

  /**
   * Constructor.
   *
   * @param aUsername
   * @param aPassword
   * @param aActive
   * @param aLocked
   * @param aNewPasswordRequired
   * @param aConsecutiveFailedLogins
   */
  public WebUser(String aUsername,
                 String aPassword,
                 Boolean aActive,
                 Boolean aLocked,
                 Boolean aNewPasswordRequired,
                 int aConsecutiveFailedLogins)
  {
    super();
    mUsername = aUsername;
    mPassword = aPassword;
    mActive = aActive;
    mLocked = aLocked;
    mNewPasswordRequired = aNewPasswordRequired;
    mConsecutiveFailedLogins = aConsecutiveFailedLogins;
  }

  /**
   * @return the username
   */
  @Column(name="USERNAME", nullable=false, length=30)
  public String getUsername()
  {
    return mUsername;
  }

  /**
   * @param aUsername the username to set
   */
  public void setUsername(String aUsername)
  {
    mUsername = aUsername;
  }

  /**
   * Get the Password.
   * @return The Password.
   */
  @Column(name="PASSWORD", nullable=false, length=32)
  public String getPassword()
  {
    return mPassword;
  }

  /**
   * Set the Password.
   * @param aPassword Password.
   */
  public void setPassword(String aPassword)
  {
    mPassword = aPassword;
  }

  /**
   * Is Active.
   * @return Is Active.
   */
  @Column(name="ACTIVE", nullable=false)
  @Type(type="true_false")
  public Boolean getActive()
  {
    return mActive;
  }

  /**
   * Set Active.
   * @param aActive Active.
   */
  public void setActive(Boolean aActive)
  {
    mActive = aActive;
  }

  /**
   * Is Locked.
   * @return Is Locked.
   */
  @Column(name="LOCKED", nullable=false)
  @Type(type="true_false")
  public Boolean getLocked()
  {
    return mLocked;
  }

  /**
   * Set Locked.
   * @param aLocked Locked.
   */
  public void setLocked(Boolean aLocked)
  {
    mLocked = aLocked;
  }

  /**
   * Is New Password Required.
   * @return Is New Password Required.
   */
  @Column(name="NEW_PASSWORD_REQUIRED", nullable=false)
  @Type(type="true_false")
  public Boolean getNewPasswordRequired()
  {
    return mNewPasswordRequired;
  }

  /**
   * Set New Password Required.
   * @param aNewPasswordRequired New Password Required.
   */
  public void setNewPasswordRequired(Boolean aNewPasswordRequired)
  {
    mNewPasswordRequired = aNewPasswordRequired;
  }

  /**
   * Number of Consecutive Failed Logins.
   * @return Consecutive Failed Logins.
   */
  @Column(name="CONSECUTIVE_FAILED_LOGINS", nullable=false)
  public int getConsecutiveFailedLogins()
  {
    return mConsecutiveFailedLogins;
  }

  /**
   * @param aConsecutiveFailedLogins
   */
  public void setConsecutiveFailedLogins(int aConsecutiveFailedLogins)
  {
    mConsecutiveFailedLogins = aConsecutiveFailedLogins;
  }

  /**
   * Get End Date of User.
   * @return End Date of User.
   */
  @Column(name="END_DATE")
  @Type(type="uk.co.hs.hibernate.JodaDateType")
  public DateTime getEndDate()
  {
    return mEndDate;
  }

  /**
   * Set End Date.
   * @param aEndDate End Date.
   */
  public void setEndDate(DateTime aEndDate)
  {
    mEndDate = aEndDate;
  }

  /**
   * Get Last Password Changed Date.
   * @return Last Password Changed Date.
   */
  @Column(name = "LAST_PASSWORD_CHANGE")
  @Type(type="uk.co.hs.hibernate.JodaDateType")
  public DateTime getLastPasswordChanged()
  {
    return mLastPasswordChanged;
  }

  /**
   * Set Last Password Changed Date.
   * @param aLastPasswordChanged Last Password Changed Date.
   */
  public void setLastPasswordChanged(DateTime aLastPasswordChanged)
  {
    mLastPasswordChanged = aLastPasswordChanged;
  }

  /**
   * Get Role.
   * @return Role.
   */
  @ManyToOne(fetch = FetchType.EAGER)
  @JoinColumn(name=ROLE_FK)
  @ForeignKey(name="WEB_USER_TO_WEB_ROLE")
  public WebRole getRole()
  {
    return mRole;
  }

  /**
   * Set the Role.
   * @param aRole Role.
   */
  public void setRole(WebRole aRole)
  {
    mRole = aRole;
  }

  /**
   * @return Password Histories.
   */
  @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER)
  @JoinColumn(name = "USER_FK")
  @ForeignKey(name = "WEB_USER_TO_WEB_PASSWD_HISTORY")
  public List<WebPasswordHistory> getPasswordHistory()
  {
    return mPasswordHistory;
  }

  /**
   * @param aPasswordHistory Password Histories.
   */
  public void setPasswordHistory(List<WebPasswordHistory> aPasswordHistory)
  {
    mPasswordHistory = aPasswordHistory;
  }

  /**
   * @return the mPreferences
   */
  @Column(name="PREFERENCES", length=4000, nullable=true)
  public String getPreferences()
  {
    return mPreferences;
  }

  /**
   * @param aWebUserPreferences the mPreferences to set
   */
  public void setPreferences(String aPreferences)
  {
    mPreferences = aPreferences;
  }
}
